package com.edu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.user.domain.dto.DoctorScheduleDTO;
import com.edu.user.domain.dto.DoctorUpdateDTO;
import com.edu.user.domain.dto.DoctorUpdateInfoDTO;
import com.edu.user.domain.dto.NotificationDTO;
import com.edu.user.domain.po.Appointment;
import com.edu.user.domain.po.Doctor;
import com.edu.user.domain.po.DoctorSchedule;
import com.edu.user.domain.po.User;
import com.edu.user.domain.vo.DoctorScheduleVO;
import com.edu.user.domain.vo.DoctorVO;
import com.edu.user.mapper.AppointmentMapper;
import com.edu.user.mapper.DoctorScheduleMapper;
import com.edu.user.service.AppointmentService;
import com.edu.user.service.DoctorScheduleService;
import com.edu.user.service.NotificationService;
import com.edu.user.utils.BeanUtils;
import com.edu.user.utils.Result;
import com.edu.user.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class DoctorScheduleServiceImpl extends ServiceImpl<DoctorScheduleMapper, DoctorSchedule> implements DoctorScheduleService {
  @Autowired
  DoctorScheduleMapper doctorScheduleMapper;
    @Autowired
    UserServiceImpl userService;
    @Autowired
    NotificationService notificationService;
    @Autowired
    AppointmentMapper appointmentMapper;
    @Autowired
    AppointmentService appointmentService;
    @Override
    public Result addDoctorSchedule(DoctorScheduleDTO scheduleDTO) {
       User user  = ThreadLocalUtil.get();
       if(user==null){
           return Result.error("请先登录");
       }
       Long id = user.getId();
     if(scheduleDTO.getDoctorId()!=id){
         return Result.error("账户不匹配");
    }
        // 检查是否存在时间冲突
        if (isScheduleConflict(scheduleDTO.getDoctorId(), scheduleDTO.getScheduleDate(), scheduleDTO.getStartTime(), scheduleDTO.getEndTime())) {
            return Result.error("该时间段已有排班，无法重复设置");
        }
        DoctorSchedule doctorSchedule = BeanUtils.copyProperties(scheduleDTO, DoctorSchedule.class);
     doctorSchedule.setCreatedAt(LocalDateTime.now());
     doctorSchedule.setUpdatedAt(LocalDateTime.now());
        save(doctorSchedule);
        return Result.success();
    }

    @Override
    public Result selectById(Integer doctorId) {
        QueryWrapper<DoctorSchedule> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("doctor_id", doctorId);

        List<DoctorSchedule> doctorSchedules = doctorScheduleMapper.selectList(queryWrapper);

        List<DoctorScheduleVO>doctorSchedulevos =new ArrayList<>();
        //判断是否超时，超时删除。
        List<DoctorSchedule> schedulesToRemove = new ArrayList<>();

        LocalDateTime currentDateTime = LocalDateTime.now();

        for (DoctorSchedule schedule : doctorSchedules) {
            LocalDateTime scheduleDateTime = LocalDateTime.of(schedule.getScheduleDate(), schedule.getEndTime());

            if (scheduleDateTime.isBefore(currentDateTime)) {
                // 如果排班时间已经过期，则执行删除操作
                doctorScheduleMapper.deleteById(schedule.getId());
                schedulesToRemove.add(schedule);
            }
        }

        // 从原始列表中移除已过期的排班
        doctorSchedules.removeAll(schedulesToRemove);

        //将数据转换为vo层
        for (DoctorSchedule doctorSchedule : doctorSchedules) {
            DoctorScheduleVO doctorScheduleVO = BeanUtils.copyProperties(doctorSchedule, DoctorScheduleVO.class);
            User user = userService.getById(doctorSchedule.getDoctorId());
            doctorScheduleVO.setName(user.getName());
            doctorSchedulevos.add(doctorScheduleVO);
        }


        // 将查询到的数据封装为 Result 对象返回给前端
        return Result.success(doctorSchedulevos);
    }

    @Override
    public boolean removeByscheduleId(Integer scheduleId) {
        QueryWrapper<Appointment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("schedules_id",scheduleId);
        List<Appointment> appointments = appointmentMapper.selectList(queryWrapper);
        for (Appointment appointment : appointments) {
            appointmentService.sendNotification("取消",appointment);
        }
        boolean isok = removeById(scheduleId);
        if (isok){
            return true;
        }else {
            return false;
        }

    }

    @Override
    public boolean isScheduleConflict(Long doctorId, LocalDate scheduleDate, LocalTime startTime, LocalTime endTime) {

        LambdaQueryWrapper<DoctorSchedule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DoctorSchedule::getDoctorId, doctorId)
                .eq(DoctorSchedule::getScheduleDate, scheduleDate)
                .and(wrapper -> wrapper.between(DoctorSchedule::getStartTime, startTime, endTime)
                        .or()
                        .between(DoctorSchedule::getEndTime, startTime, endTime)
                        .or()
                        .lt(DoctorSchedule::getStartTime, startTime)
                        .gt(DoctorSchedule::getEndTime, endTime));
        return count(queryWrapper) > 0;
    }

    @Override
    public Result updateDoctorSchedule(DoctorUpdateInfoDTO updateDTO) {

        System.out.println(updateDTO);
        DoctorSchedule existingSchedule = getById(updateDTO.getScheduleId());
        if (existingSchedule == null) {
            return Result.error("排班信息不存在");
        }
        // 检查时间冲突
        if (isScheduleConflict(updateDTO.getDoctorId(), updateDTO.getScheduleDate(), updateDTO.getStartTime(), updateDTO.getEndTime())) {
            return Result.error("该时间段已有排班，无法重复设置");
        }
        DoctorSchedule updatedSchedule = BeanUtils.copyProperties(updateDTO, DoctorSchedule.class);
        updatedSchedule.setId(updateDTO.getScheduleId());
        updatedSchedule.setCreatedAt(existingSchedule.getCreatedAt());
        updatedSchedule.setUpdatedAt(LocalDateTime.now());
        System.out.println(updatedSchedule);
        updateById(updatedSchedule);
        return Result.success("修改成功");
    }


}
